package by.gravity.drive_track.fragments;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import by.gravity.common.fragment.CommonFragment;
import by.gravity.drive_track.AppIntents;
import by.gravity.drive_track.R;
import by.gravity.drive_track.adapter.RouteAdapter;
import by.gravity.drive_track.model.Favorite;
import by.gravity.drive_track.model.STATUS;
import by.gravity.drive_track.model.places.Place;
import by.gravity.drive_track.model.places.Places;
import by.gravity.drive_track.model.route.Route;
import by.gravity.drive_track.provider.DriveNTrackProvider;
import by.gravity.drive_track.provider.listeners.OnPlaceSearchCompleteListener;
import by.gravity.drive_track.ui.listView.SwipeDismissListViewTouchListener;
import by.gravity.drive_track.widget.AutoCompleteTextView;

public class RouteFragment extends CommonFragment implements AppIntents {

	public static final String TAG = RouteFragment.class.getSimpleName();

	private ListView mListView;

	private RouteAdapter mAdapter;

	private Button mAddButton;

	private DriveNTrackProvider mProvider;

	private AutoCompleteTextView mStartPositionName;

	private AutoCompleteTextView mFinishPositionName;

	private ImageView mCarModeView;

	private ImageView mWalkModeView;

	private List<String> mSearchFilter;

	private int countMarkers = 0;

	private Handler mHandler;

	private List<Runnable> mRunnedSearchRunnable;

	public enum SELECTED_MODE {
		WALK, CAR;
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
		mProvider = DriveNTrackProvider.get(getActivity());
		mHandler = new Handler();
		mRunnedSearchRunnable = new ArrayList<Runnable>();
		mSearchFilter = Arrays.asList(getResources().getStringArray(R.array.search_filter));
		init();
		mListView = (ListView) getView().findViewById(R.id.list);
		LinearLayout bottomLayout = (LinearLayout) LayoutInflater.from(getActivity()).inflate(
				R.layout.route_bottom_button, null, false);
		mAddButton = (Button) bottomLayout.findViewById(R.id.addPoint);
		mAdapter = new RouteAdapter(getActivity(), R.layout.route_item, getRouteList());
		mListView.addFooterView(bottomLayout);
		mListView.setAdapter(mAdapter);
		mAddButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View paramView) {
				AddRouteDialog.newInstance(countMarkers).show(getFragmentManager(),
						AddRouteDialog.class.getSimpleName() + countMarkers);
			}
		});

		mCarModeView = (ImageView) getView().findViewById(R.id.car_mode);
		mWalkModeView = (ImageView) getView().findViewById(R.id.walk_mode);

		SwipeDismissListViewTouchListener touchListener = new SwipeDismissListViewTouchListener(mListView,
				new SwipeDismissListViewTouchListener.OnDismissCallback() {
					@Override
					public void onDismiss(ListView listView, int[] reverseSortedPositions) {
						for (int position : reverseSortedPositions) {
							mAdapter.remove(mAdapter.getItem(position));
							Intent intent = new Intent(REMOVE_POINT_INTENT);
							intent.putExtra(ARG_POINT_NUMBER, position);
							sendBroadcast(intent);
						}
						mAdapter.notifyDataSetChanged();
					}
				});
		mListView.setOnTouchListener(touchListener);
		mListView.setOnScrollListener(touchListener.makeScrollListener());

	}

	private void setSelectedMode(SELECTED_MODE mode) {
		if (isAdded()) {
			if (mode == SELECTED_MODE.CAR) {
				mCarModeView.setBackgroundColor(getResources().getColor(R.color.blue));
				mWalkModeView.setBackgroundColor(getResources().getColor(android.R.color.transparent));
			} else if (mode == SELECTED_MODE.WALK) {
				mWalkModeView.setBackgroundColor(getResources().getColor(R.color.blue));
				mCarModeView.setBackgroundColor(getResources().getColor(android.R.color.transparent));
			}
		}
	}

	private void init() {
		LinearLayout startPositionLayout = (LinearLayout) getView().findViewById(R.id.startItem);
		startPositionLayout.setTag(-2);

		LinearLayout finishPositionLayout = (LinearLayout) getView().findViewById(R.id.finishItem);
		finishPositionLayout.setTag(-1);

		mStartPositionName = (AutoCompleteTextView) startPositionLayout.findViewById(R.id.text);

		mFinishPositionName = (AutoCompleteTextView) finishPositionLayout.findViewById(R.id.text);

		TextWatcher startTextWatcher = new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				search(s.toString(), mStartPositionName, -2);
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count, int after) {

			}

			@Override
			public void afterTextChanged(Editable s) {

			}
		};

		TextWatcher finishTextWatcher = new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				search(s.toString(), mFinishPositionName, -1);
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count, int after) {

			}

			@Override
			public void afterTextChanged(Editable s) {

			}
		};

		mStartPositionName.setText(getString(R.string.my_location));
		mStartPositionName.addTextChangedListener(startTextWatcher);

		mFinishPositionName.addTextChangedListener(finishTextWatcher);
	}

	private String prevSearch;

	private void search(final String query, final AutoCompleteTextView textView, int number) {
		if (textView.getText().length() < 2) {
			cancelAllSearhRunnable();
			return;
		}

		if (filterSearch(query)) {
			return;
		}

		if (query.equalsIgnoreCase(prevSearch)) {
			return;
		}

		prevSearch = query;

		cancelAllSearhRunnable();
		Runnable searchRunnable = getSearchRunnable(query, textView, number);
		mHandler.postDelayed(searchRunnable, 600);

	}

	private Runnable getSearchRunnable(final String query, final AutoCompleteTextView textView, final int number) {
		Runnable runnable = new Runnable() {

			@Override
			public void run() {
				mProvider.searchPlace(query, new OnPlaceSearchCompleteListener() {

					@Override
					public void onSuccess(final Places places) {
						if (getActivity() == null) {
							return;
						}
						final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
								android.R.layout.simple_dropdown_item_1line);
						for (Place place : places.getPlaces()) {
							adapter.add(place.getFormattedAddress());
						}
						textView.setAdapter(adapter);
						adapter.notifyDataSetChanged();
						textView.setOnItemClickListener(new OnItemClickListener() {

							@Override
							public void onItemClick(AdapterView<?> paramAdapterView, View paramView, int paramInt,
									long paramLong) {
								Intent intent = new Intent(ON_POINT_NAME_SELECTED_INTENT);
								intent.putExtra(ARG_POINT_NUMBER, number);
								intent.putExtra(ARG_POINT_LOCATION, places.getPlaces().get(paramInt).getGeometry()
										.getLocation());
								sendBroadcast(intent);
							}
						});

					}

					@Override
					public void onError(STATUS status) {

					}
				});

			}
		};

		addSearchRunnable(runnable);
		return runnable;
	}

	private void cancelAllSearhRunnable() {
		for (Runnable runnable : mRunnedSearchRunnable) {
			mHandler.removeCallbacks(runnable);
		}
	}

	private void addSearchRunnable(Runnable runnable) {
		mRunnedSearchRunnable.add(runnable);
	}

	private boolean filterSearch(String query) {
		for (String string : mSearchFilter) {
			if (query.startsWith(string)) {
				return true;
			}
		}

		return false;
	}

	private List<Route> getRouteList() {
		List<Route> result = new ArrayList<Route>();
		// for (int i = 0; i < 20; i++) {
		// result.add(new Route("Route " + i));
		// }
		return result;
	}

	@Override
	protected void addIntentFilter(IntentFilter filter) {
		filter.addAction(ON_FAVORITE_CLICK_INTENT);
		filter.addAction(ON_GEO_CLICK_INTENT);
		filter.addAction(ON_REMOVE_CLICK_INTENT);
		filter.addAction(ADD_POINT_NAME_INTENT);
		filter.addAction(ADD_ADDITIONAL_POINT_INTENT);
		filter.addAction(ON_DRIVIND_MODE_CLICK_INTENT);
		filter.addAction(ON_WALKING_MODE_CLICK_INTENT);
		filter.addAction(ADD_ADDITION_POINT_FROM_FAVORITE);
	}

	@Override
	protected void onBroadcastReceive(Intent intent, String intentAction) {
		if (intentAction.equals(ON_GEO_CLICK_INTENT)) {
		} else if (intent.getAction().equals(ADD_POINT_NAME_INTENT)) {
			int number = intent.getIntExtra(ARG_POINT_NUMBER, 0);
			String pointName = intent.getStringExtra(ARG_POINT_NAME);
			if (number == -2) {
				mStartPositionName.setText(pointName);
			} else if (number == -1) {
				mFinishPositionName.setText(pointName);
			} else {
				addAdditionalPoint(pointName);
			}
		}
//		else if (intentAction.equals(ADD_ADDITIONAL_POINT_INTENT)) {
//			String pointName = intent.getStringExtra(ARG_POINT_NAME);
//			addAdditionalPoint(pointName);
//		} 
		else if (intentAction.equals(ON_DRIVIND_MODE_CLICK_INTENT)) {
			setSelectedMode(SELECTED_MODE.CAR);
		} else if (intentAction.equals(ON_WALKING_MODE_CLICK_INTENT)) {
			setSelectedMode(SELECTED_MODE.WALK);
		}
	}

	private void addAdditionalPoint(String pointName) {
		countMarkers++;
		mAdapter.getList().add(new Route(pointName));
		mAdapter.notifyDataSetChanged();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		return inflater.inflate(R.layout.f_routes, null);
	}

}
